import React from "react";
import { Toast } from "antd-mobile";
// import axios from "axios";
import {API} from'../../utils/api'

import "./index.css";

import NavHeader from '../../components/NavHeader'
// 导入获取定位城市数据的工具函数
import { getCurrentCity } from "../../utils";

// 引入 长列表组件
// import List from "react-virtualized/dist/commonjs/List";
import { List, AutoSizer } from "react-virtualized";
// 数据格式化的方法
// list: [{}, {}]
const formatCityData = (list) => {
  const cityList = {};
  // const cityIndex = []

  // 1 遍历list数组
  list.forEach((item) => {
    // 2 获取每一个城市的首字母
    const first = item.short.substr(0, 1);
    // 3 判断 cityList 中是否有该分类
    if (cityList[first]) {
      // 4 如果有，直接往该分类中push数据
      // cityList[first] => [{}, {}]
      cityList[first].push(item);
    } else {
      // 5 如果没有，就先创建一个数组，然后，把当前城市信息添加到数组中
      cityList[first] = [item];
    }
  });

  // 获取索引数据
  const cityIndex = Object.keys(cityList).sort();

  return {
    cityList,
    cityIndex,
  };
};
// 每行城市首字母索引所在行的高度
const TITLE_HEIGHT = 36;
// 每个城市名称的高度
const NAME_HEIGHT = 50;
// 后台数据库中有房源信息的城市
const HOST_CITY = ['北京', '上海', '广州', '深圳']

export default class CityList extends React.Component {

  constructor(props) {
    super(props)
    this.listComponent = React.createRef() // list 组件的 scrollToRow 方法是一个组件实例的方法 所以要先通过 ref 获得组件的实例
    this.state = {
      cityList: {},
      cityIndex: [],
      activeIndex: 0 // 右侧索引是否高亮显示的索引号
    };
  }

  

  // 封装获取城市列表数据的方法
  async getCityList() {
    const res = await API.get("http://localhost:8080/area/city?level=1"); // 获取城市基础列表
    const result = await API.get("http://localhost:8080/area/hot"); // 获取热门城市列表
    const currentCity = await getCurrentCity(); // 获取当前定位城市数据
    //  console.log('城市列表数据',res);
    //  调用封装好的数据转化的方法
    const { cityList, cityIndex } = formatCityData(res.data.body);
    //  console.log(result)
    //  添加热门城市数据和索引
    cityList["hot"] = result.data.body; // 以 { hot: {}}形式添加到城市列表数组对象中
    cityIndex.unshift("hot");
    //  添加定位城市数据和索引
    cityList["#"] = [currentCity];
    cityIndex.unshift("#");
    console.log("转化后的数据", cityList, cityIndex);

    // 把转化、合并到一起的数据传给 state
    this.setState(() => {
      return {
        cityList,
        cityIndex,
      };
    });
  }

// 封装切换城市的方法
  changeCity( {label,value} ) {
  // console.log(item); // {label:'郑州',value:'xxx'}
    if (HOST_CITY.indexOf(label) > -1) {
      // 有房源数据
      localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
      // 自动跳转路由到上一页
      this.props.history.go(-1)
    } else {
      // 没有房源数据
      Toast.info('该城市无房源',1,null,false)
    }
}

  // 长列表 list组件渲染每一行的方法 渲染城市列表
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // Index of row within collection 索引号
    isScrolling, // The List is currently being scrolled  当前项是否正在滚动中
    isVisible, // This row is visible within the List (eg it is not an overscanned row)  当前项在List中是可见的
    style, // Style object to be applied to row (to position it) 重点属性：一定要给每一个行数添加该样式
  }) => {
    // console.log(index);
    // 获取每一行的首字母
    const cityLetter = this.state.cityIndex[index];
    // console.log(cityLetter);
    // 根据首字母获取指定字母索引下的城市列表数据
    const currentCityList = this.state.cityList[cityLetter];
    // console.log(currentCityList);
    return (
      <div key={key} style={style} className="city">
        <div className="title">{this.formatCityLetter(cityLetter)}</div>
        {currentCityList.map((item) => (
          <div className="name" key={item.value} onClick={() => this.changeCity(item)}>
            {item.label}
          </div>
        ))}
      </div>
    );
  };
  // 封装格式化城市首字母的方法
  formatCityLetter = (cityLetter) => {
    switch (cityLetter) {
      case "#":
        return "当前定位";
      case "hot":
        return "热门城市";
      default:
        return cityLetter.toUpperCase();
      // break;
    }
  };
async componentDidMount() {
   await this.getCityList();
    // 在这个钩子函数中 调用 measureAllRows 方法，提前计算 List 组件中每一行的高度，实现 scrollToRow 的精确跳转
    // 此时报错信息 提示 index -1 因为此时调用这个方法时没有获得数据
  // 解决：保证这个方法 是在获取到数据后 执行(getCityList是一个异步方法)
    this.listComponent.current.measureAllRows()
  }
  // 封装动态计算每行高度
  getRowHeight = ({ index }) => {
    let { cityIndex, cityList } = this.state;
    // console.log(this);
    // console.log(index);
    // 索引的高度 + 数量 * 每个城市的高度
    return cityList[cityIndex[index]].length * NAME_HEIGHT + TITLE_HEIGHT;
  };
  // 封装右侧索引方法
  renderCityIndex = () => {
    const { cityIndex } = this.state;
    return (
      cityIndex.map((item, index) => (
        <li className="city-index-item" key={index} onClick={() => { this.listComponent.current.scrollToRow(index) }}>
          {/*判断一下，如果高亮状态的索引等于当前索引，那么就设置高亮样式*/}
          <span className={this.state.activeIndex === index ? "index-active" : ''}>
            {/* 把索引中的 hot 替换为 热 ，小写字母替换为大写字母 */}
          {item === 'hot' ? '热' : item.toUpperCase()}
          </span>
        </li>
      ) )
    )
  }
// 封装滚动列表时 右侧对应索引高亮显示的方法
  onRowRendered = ( { startIndex } ) =>{
    // console.log(startIndex);
    if (this.state.activeIndex !== startIndex) { // 确保当滚动列表是同一个分类的城市时 避免不必要的 state 更新 提高性能
      this.setState({
          activeIndex: startIndex
      })
  }
}
  render() {
    return (
      <div className="citylist-container">
        {/* <NavBar
          className="navbar"
          // 模式 默认值是 dark
          mode="light"
          // 左侧小图片
          icon={<i className="iconfont icon-back"></i>}
          // 左侧按钮的点击事件
          onLeftClick={() => this.props.history.go(-1)}
        >
          城市列表
        </NavBar> */}
        <NavHeader>
            城市列表
        </NavHeader>

        {/* 城市列表组件 */}
        <AutoSizer>
          {({ height, width }) => (
            <List
              height={height}
              width={width}
              rowCount={this.state.cityIndex.length}
              rowHeight={this.getRowHeight}
              rowRenderer={this.rowRenderer}
              onRowsRendered={this.onRowRendered} // 判断当前这一行是否渲染完成
              ref={this.listComponent}
              scrollToAlignment="start"
            />
          )}
        </AutoSizer>

        {/* 右侧索引列表 */}
        <ul className="city-index">
          { this.renderCityIndex() }
        </ul>
      </div>
    );
  }
}
